/**
 * by ward @ harrydeep@163.com 
 * 2019
 */
package top.wardyan.common.util;

import java.security.SecureRandom;
import java.sql.Timestamp;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/**
 * @author ward 用途: 版本: 创建: 更新:
 */
public class AESUtil {
	// private static final Logger logger =Logger.getLogger(AESUtil.class);
	private static final String	defaultCharset	= "UTF-8";
	private static final String	KEY_AES			= "AES";
	//@SuppressWarnings("unused")
	//private static final String	KEY				= "123456";

	/**
	 * 加密
	 * @param data	需要加密的内容
	 * @param key 	加密密码
	 * @return
	 */
	public static String encrypt(String data, String key) {
		return doAES(data, key, Cipher.ENCRYPT_MODE);
	}

	/**
	 * 解密
	 * @param data	待解密内容
	 * @param key	解密密钥
	 * @return
	 */
	public static String decrypt(String data, String key) {
		return doAES(data, key, Cipher.DECRYPT_MODE);
	}

	/**
	 * 加解密
	 * 
	 * @param data		待处理数据
	 * @param password	密钥
	 * @param mode		加解密mode
	 * @return
	 */
	private static String doAES(String data, String key, int mode) {
		try {
			/**
			if (StringUtils.isBlank(data) || StringUtils.isBlank(key)) {
				return null;
			}
			**/
			// 判断是加密还是解密
			boolean encrypt = mode == Cipher.ENCRYPT_MODE;
			byte[] content;
			// true 加密内容 false 解密内容
			if (encrypt) {
				content = data.getBytes(defaultCharset);
			} else {
				content = parseHexStr2Byte(data);
			}
			SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
	        random.setSeed(key.getBytes());
			// 1.构造密钥生成器，指定为AES算法,不区分大小写
			KeyGenerator kgen = KeyGenerator.getInstance(KEY_AES);
			// 2.根据ecnodeRules规则初始化密钥生成器
			// 生成一个128位的随机源,根据传入的字节数组
			kgen.init(128, random);
			// 3.产生原始对称密钥
			SecretKey secretKey = kgen.generateKey();
			// 4.获得原始对称密钥的字节数组
			byte[] enCodeFormat = secretKey.getEncoded();
			// 5.根据字节数组生成AES密钥
			SecretKeySpec keySpec = new SecretKeySpec(enCodeFormat, KEY_AES);
			// 6.根据指定算法AES自成密码器
			Cipher cipher = Cipher.getInstance(KEY_AES);// 创建密码器
			// 7.初始化密码器，第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作，第二个参数为使用的KEY
			cipher.init(mode, keySpec);// 初始化
			byte[] result = cipher.doFinal(content);
			if (encrypt) {
				// 将二进制转换成16进制
				return parseByte2HexStr(result);
			} else {
				return new String(result, defaultCharset);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 将二进制转换成16进制
	 * 
	 * @param buf
	 * @return
	 */
	public static String parseByte2HexStr(byte buf[]) {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < buf.length; i++) {
			String hex = Integer.toHexString(buf[i] & 0xFF);
			if (hex.length() == 1) {
				hex = '0' + hex;
			}
			sb.append(hex.toUpperCase());
		}
		return sb.toString();
	}

	/**
	 * 将16进制转换为二进制
	 * 
	 * @param hexStr
	 * @return
	 */
	public static byte[] parseHexStr2Byte(String hexStr) {
		if (hexStr.length() < 1) {
			return null;
		}
		byte[] result = new byte[hexStr.length() / 2];
		for (int i = 0; i < hexStr.length() / 2; i++) {
			int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
			int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
			result[i] = (byte) (high * 16 + low);
		}
		return result;
	}

	
	
	
	
	
	
	
	
	
	
	
	
	
	public static void main(String[] args) throws Exception {
		//String content = "{'repairPhone':'18547854787','customPhone':'12365478965','captchav':'58m7'}";
		String content = "一想到你我就\r\n" + 
				"Wu\r\n" + 
				"空恨别梦久\r\n" + 
				"Wu\r\n" + 
				"烧去纸灰埋烟柳\r\n" + 
				"于鲜活的枝丫\r\n" + 
				"凋零下的无暇\r\n" + 
				"是收获谜底的代价\r\n" + 
				"余晖沾上 远行人的发\r\n" + 
				"他洒下手中牵挂\r\n" + 
				"于桥下\r\n" + 
				"前世迟来者 （擦肩而过）\r\n" + 
				"掌心刻（来生记得）\r\n" + 
				"你眼中烟波滴落一滴墨 wo\r\n" + 
				"若佛说 （无牵无挂）\r\n" + 
				"放下执着 （无相无色）\r\n" + 
				"我怎能 波澜不惊 去附和\r\n" + 
				"一想到你我就\r\n" + 
				"Wu\r\n" + 
				"恨情不寿 总于苦海囚\r\n" + 
				"Wu\r\n" + 
				"新翠徒留 落花影中游\r\n" + 
				"Wu\r\n" + 
				"相思无用 才笑山盟旧\r\n" + 
				"Wu\r\n" + 
				"谓我何求\r\n" + 
				"谓我何求\r\n" + 
				"种一万朵莲花\r\n" + 
				"在众生中发芽\r\n" + 
				"等红尘一万种解答\r\n" + 
				"念珠落进 时间的泥沙\r\n" + 
				"待 割舍诠释慈悲\r\n" + 
				"的读法\r\n" + 
				"前世迟来者 （擦肩而过）\r\n" + 
				"掌心刻 （来生记得）\r\n" + 
				"你眼中烟波滴落一滴墨 wo\r\n" + 
				"若佛说 （无牵无挂）\r\n" + 
				"放下执着 （无相无色）\r\n" + 
				"我怎能 波澜不惊 去附和\r\n" + 
				"一想到你我就\r\n" + 
				"Wu\r\n" + 
				"恨情不寿 总于苦海囚\r\n" + 
				"Wu\r\n" + 
				"新翠徒留 落花影中游\r\n" + 
				"Wu\r\n" + 
				"相思无用 才笑山盟旧\r\n" + 
				"Wu\r\n" + 
				"谓我何求";
		
		content += content;
		content += content;
		content += content;
		content += content;
		content += content;
		content += content;
		content += content;
		content += content;
		content += content;
		content += content;
		content += content;
		content += content;
		content += content;
		content += content;
		
		System.out.println(content.length());
		//System.out.println("加密前：" + content);
		//System.out.println("加密密钥和解密密钥：" + KEY);
		Timestamp now = DateUtil.getCurrentTimestamp();
		String encrypt = encrypt(content, "hello");
		System.out.println(DateUtil.getCurrentTimestamp().getTime() - now.getTime());
//		System.out.println("加密后：" + encrypt);
//		String decrypt = decrypt(encrypt, KEY);
//		System.out.println("解密后：" + decrypt);
	}
}
